' 
' Copyright (C) 2014 Infinity CCS Ltd (http://www.infinityccs.com/)
' Copyright (C) 2008 Sasa Coh <sasacoh@gmail.com>
'
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program.  If not, see <http://www.gnu.org/licenses/>. 
'/

Imports System.Runtime.InteropServices
Imports System
Imports System.Text
Imports Infinity.pjsipNET.Common

Public Class pjsipPresenceAndMessaging
  Inherits Presence.IPresenceAndMessaging
#Region "Dll declarations"
  <DllImport("Infinity.pjsip.dll", EntryPoint:="dll_addBuddy", CallingConvention:=CallingConvention.Cdecl)>
  Private Shared Function dll_addBuddy(uri As String, subscribe As Boolean) As Integer
  End Function

  <DllImport("Infinity.pjsip.dll", EntryPoint:="dll_removeBuddy", CallingConvention:=CallingConvention.Cdecl)>
  Private Shared Function dll_removeBuddy(buddyId As Integer) As Integer
  End Function

  <DllImport("Infinity.pjsip.dll", EntryPoint:="dll_sendMessage", CallingConvention:=CallingConvention.Cdecl)>
  Private Shared Function dll_sendMessage(buddyId As Integer, uri As String, message As String) As Integer
  End Function

  <DllImport("Infinity.pjsip.dll", EntryPoint:="dll_setStatus", CallingConvention:=CallingConvention.Cdecl)>
  Private Shared Function dll_setStatus(accId As Integer, presence_state As Integer) As Integer
  End Function
#End Region

#Region "Callback declarations"
  Delegate Function delOnMessageReceivedCallback(from As String, message As String) As Integer
  Delegate Function delOnBuddyStatusChangedCallback(buddyId As Integer, status As Integer, statusText As String) As Integer

  <DllImportAttribute("Infinity.pjsip.dll", CallingConvention:=CallingConvention.Cdecl)>
  Private Shared Function setCallback_onMessageReceived(cb As delOnMessageReceivedCallback) As Integer
  End Function
  <DllImportAttribute("Infinity.pjsip.dll", CallingConvention:=CallingConvention.Cdecl)>
  Private Shared Function setCallback_onBuddyStatusChanged(cb As delOnBuddyStatusChangedCallback) As Integer
  End Function

  Shared mrdel As delOnMessageReceivedCallback = New delOnMessageReceivedCallback(AddressOf onMessageReceived)
  Shared bscdel As delOnBuddyStatusChangedCallback = New delOnBuddyStatusChangedCallback(AddressOf onBuddyStatusChanged)

#End Region

#Region "Constructor"
  Private Shared _instance As pjsipPresenceAndMessaging = Nothing
  Public Shared ReadOnly Property Instance As pjsipPresenceAndMessaging
    Get
      If _instance Is Nothing Then _instance = New pjsipPresenceAndMessaging()
      Return _instance
    End Get
  End Property

  Private Sub New()
    setCallback_onBuddyStatusChanged(bscdel)
    setCallback_onMessageReceived(mrdel)
  End Sub
#End Region

#Region "Public Methods"

  ''' <summary>
  ''' Add new entry in a buddy list and subscribe presence
  ''' </summary>
  ''' <param name="name">Buddy address (without hostname part</param>
  ''' <param name="presence">subscribe presence flag</param>
  ''' <returns></returns>
  Public Overrides Function addBuddy(name As String, presence As Boolean, accountKey As String) As Integer
    Dim sipuri As String = ""

    If Not pjsipStackProxy.Instance.IsInitialized Then Return -1

    '// check if name contains URI
    If name.IndexOf("sip:") = 0 Then
      '// do nothing...
      sipuri = name
    Else
      sipuri = "sip:" + name + "@" + Config.Account(accountKey).HostName
    End If
    '// check transport - if TCP add transport=TCP
    sipuri = pjsipStackProxy.Instance.SetTransport(accountKey, sipuri)

    Return dll_addBuddy(sipuri, presence)
  End Function

  ''' <summary>
  ''' 
  ''' </summary>
  ''' <param name="buddyId"></param>
  ''' <returns></returns>
  Public Overrides Function delBuddy(buddyId As Integer) As Integer
    Return dll_removeBuddy(buddyId)
  End Function

  ''' <summary>
  ''' Send an instance message
  ''' </summary>
  ''' <param name="destAddress"></param>
  ''' <param name="message"></param>
  ''' <returns></returns>
  Public Overrides Function sendMessage(destAddress As String, message As String, accountKey As String) As Integer
    If Not pjsipStackProxy.Instance.IsInitialized Then Return -1

    Dim sipuri As String = ""

    '// check if name contains URI
    If (destAddress.IndexOf("sip:") = 0) Then
      '// do nothing...
      sipuri = destAddress
    Else
      sipuri = "sip:" + destAddress + "@" + Config.Account(accountKey).HostName
    End If
    '// set transport
    sipuri = pjsipStackProxy.Instance.SetTransport(accountKey, sipuri)

    Return dll_sendMessage(Config.Account(accountKey).pjsipIndex, sipuri, message)
  End Function

  ''' <summary>
  ''' 
  ''' </summary>
  ''' <param name="destAddress"></param>
  ''' <param name="message"></param>
  ''' <returns></returns>
  Public Overrides Function sendMessage(destAddress As String, message As String) As Integer
    Return sendMessage(destAddress, message, Config.DefaultAccountKey)
  End Function

  ''' <summary>
  ''' Set presence status
  ''' </summary>
  ''' <param name="accountKey"></param>
  ''' <param name="status"></param>
  ''' <returns></returns>
  Public Overrides Function setStatus(accountKey As String, status As EUserStatus) As Integer
    If (Not pjsipStackProxy.Instance.IsInitialized) Then Return -1
    If Config.Account(accountKey).pjsipRegStatus <> 200 Then Return -1
    If (Not Config.PublishEnabled) Then Return -1

    Return dll_setStatus(Config.Account(accountKey).pjsipIndex, CInt(status))
  End Function

#End Region

#Region "Callbacks"
  Private Shared Function onMessageReceived(from As String, text As String) As Integer
    Instance.BaseMessageReceived(from.ToString(), text.ToString())
    Return 1
  End Function

  Private Shared Function onBuddyStatusChanged(buddyId As Integer, status As Integer, text As String) As Integer
    Instance.BaseBuddyStatusChanged(buddyId, status, text.ToString())
    Return 1
  End Function
#End Region
End Class